package AnotherView;

import PangController.CollisionManager;
import PangController.GameEngine;
import PangController.GameOverException;
import PangModel.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;

/**
 * Created by baraaorabi on 5/12/15.
 */
public class Game extends Canvas {
    private final GameEngine gameEngine;
    private BufferStrategy strategy;
    //private boolean waitingForKeyPress = true;
    private boolean leftPressed = false;
    private boolean rightPressed = false;
    private boolean firePressed = false;
    private ArrayList<Ball> balls = new ArrayList<>();
    private ArrayList<Hero> heroes = new ArrayList<>();
    private ArrayList<Barrier> barriers = new ArrayList<>();

    public static final int GAME_PACE = 0;

    public static final int HERO_HEIGHT =50;
    public static final int HERO_WIDTH =50;

    public static final Dimension GAME_DIMENSION = new Dimension(500, 500);

    public static final int HERO_INDEX = 0;
    public static final int BALL_INDEX = 1;
    public static final int ANIMAL_INDEX = 2;
    public static final int BULLET_INDEX = 3;
    public static final int BARRIER_INDEX = 4;
    public static final int ITEM_INDEX = 5;
    public static final int WEAPON_INDEX = 6;
    private boolean gameRunning = true;
  //  private CollisionManager collisionManager = new CollisionManager();


    public Game() {
        // create a frame to contain our game
        Barrier b2 = new Barrier(50,50);
        b2.setCoordinates(50, 50);
        Ball bb = new Ball(3,Ball.BALL_SPLITTED_DIRECTION_LEFT, new Point(50,50));
        System.out.println(b2.includes(bb));
        System.out.println(bb.includes(b2));

        JFrame container = new JFrame("Pang");

        // get hold the content of the frame and set up the resolution of the game
        JPanel panel = (JPanel) container.getContentPane();
        panel.setPreferredSize(new Dimension(500,500));
        panel.setLayout(null);

        // setup our canvas size and put it into the content of the frame
        setBounds(0,0,800,600);
        panel.add(this);

        // Tell AWT not to bother repainting our canvas since we're
        // going to do that our self in accelerated mode
        setIgnoreRepaint(true);

        // finally make the window visible
        container.pack();
        container.setResizable(false);
        container.setVisible(true);

        // add a listener to respond to the user closing the window. If they
        // do we'd like to exit the game
        container.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        // add a key input system (defined below) to our canvas
        // so we can respond to key pressed
        addKeyListener(new KeyInputHandler());

        // request the focus so key events come to us
        requestFocus();

        // create the buffering strategy which will allow AWT
        // to manage our accelerated graphics
        createBufferStrategy(2);
        strategy = getBufferStrategy();

        // initialise the entities in our game so there's something
        // to see at startup

        gameEngine = new GameEngine(1);
        /*
        Hero h = null;
        h = new Hero();

        h.setCoordinates((double) GAME_DIMENSION.getWidth() / 2 - HERO_WIDTH, (double) GAME_DIMENSION.getHeight() - HERO_HEIGHT - 5);
        heroes.add(h);

        Ball b;
        b = new Ball(3, GameObject.BALL_SPLITTED_DIRECTION_LEFT, new Point((int) GAME_DIMENSION.getWidth() / 2, (int) GAME_DIMENSION.getHeight() / 2));
        balls.add(b);

        b = new Ball(3, GameObject.BALL_SPLITTED_DIRECTION_RIGHT, new Point((int) GAME_DIMENSION.getWidth() / 2, (int) GAME_DIMENSION.getHeight() / 2));
        balls.add(b);


        Barrier left = null;
        left = new Barrier(5,(int) GameMap.GAME_DIMENSION.getHeight());
        left.setCoordinates(-5, 0);
        Barrier right = null;
        right = new Barrier(5, (int) GameMap.GAME_DIMENSION.getHeight());
        right.setCoordinates((int) GameMap.GAME_DIMENSION.getWidth()-1, 0);
        Barrier top = null;
        top = new Barrier((int) GameMap.GAME_DIMENSION.getWidth(),5);
        top.setCoordinates(0, -5);
        Barrier bottom = null;
        bottom = new Barrier((int) GameMap.GAME_DIMENSION.getWidth(), 5);
        bottom.setCoordinates(0, (int) GameMap.GAME_DIMENSION.getHeight() - 1);

        barriers.add(left);barriers.add(right);
        barriers.add(top);barriers.add(bottom);
        */
    }


    private class KeyInputHandler implements KeyListener {
        @Override
        public void keyTyped(KeyEvent e) {

        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                leftPressed = true;
            }
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                rightPressed = true;
            }
            if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                firePressed = true;
            }
        }
        //hihih

        @Override
        public void keyReleased(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                leftPressed = false;
            }
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                rightPressed = false;
            }
            if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                firePressed = false;
            }
        }
    }

    public static void main(String argv[]) {
        Game g = new Game();

        // Start the main game loop, note: this method will not
        // return until the game has finished running. Hence we are
        // using the actual main thread to run the game.
        g.gameLoop();
    }


    public void gameLoop() {
        long lastLoopTime = System.currentTimeMillis();

        // keep looping round til the game ends
        while (gameRunning) {
            // work out how long its been since the last update, this
            // will be used to calculate how far the entities should
            // move this loop
            long delta = System.currentTimeMillis() - lastLoopTime;
            lastLoopTime = System.currentTimeMillis();

            // Get hold of a graphics context for the accelerated
            // surface and blank it out
            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
            g.setColor(Color.black);
            g.fillRect(0, 0, 500, 500);


            // finally, we've completed drawing so clear up the graphics
            // and flip the buffer over

         //   collisionManager.checkBarrierCollisions(barriers, heroes, balls, new ArrayList<Animal>(), new ArrayList<Item>());

            if ((leftPressed) && (!rightPressed)) {

                gameEngine.moveHero(GameObject.LEFT);

            } else if ((rightPressed) && (!leftPressed)) {
                gameEngine.moveHero(GameObject.RIGHT);
            }
           /* balls.get(0).move();
            balls.get(1).move();*/
            try {
                gameEngine.tick();
            } catch (GameOverException e) {
                e.printStackTrace();
                System.out.println("Game is finished");
            }


            // if we're pressing fire, attempt to fire
            if (firePressed)
            {
                gameEngine.shoot();
                firePressed = false;
            }

         /*   heroes.get(0).draw(g);
            balls.get(0).draw(g);
            balls.get(1).draw(g);
            barriers.get(0).draw(g);
            barriers.get(1).draw(g);
            barriers.get(2).draw(g);
            barriers.get(3).draw(g);*/
            gameEngine.drawObjects(g);

            g.dispose();
            strategy.show();

            // finally pause for a bit. Note: this should run us at about
            // 100 fps but on windows this might vary each loop due to
            // a bad implementation of timer
            try { Thread.sleep(10); } catch (Exception e) {e.printStackTrace();}
        }
    }


}
